#include "sdcard.h"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"

// 日志标签
static const char *TAG = "sdcard";

// 静态变量
static sdmmc_card_t *card = NULL;

// 初始化 SD 卡
esp_err_t sdcard_init(void) {
    esp_err_t ret;

    ESP_LOGI(TAG, "Initializing SD card");
    ESP_LOGI(TAG, "Using SPI peripheral");

    // 初始化主机配置
    sdmmc_host_t host = SDSPI_HOST_DEFAULT();

    // SPI 总线配置
    spi_bus_config_t bus_cfg = {
        .mosi_io_num = PIN_NUM_MOSI,
        .miso_io_num = PIN_NUM_MISO,
        .sclk_io_num = PIN_NUM_CLK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4000,
    };
    ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize bus.");
        return ret;
    }

    // SD 卡设备配置
    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
    slot_config.gpio_cs = PIN_NUM_CS;
    slot_config.host_id = host.slot;

    // 文件系统挂载配置
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 5,
        .allocation_unit_size = 16 * 1024,
    };

    // 挂载文件系统
    ret = esp_vfs_fat_sdspi_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &card);
    if (ret != ESP_OK) {
        if (ret == ESP_FAIL) {
            ESP_LOGE(TAG, "Failed to mount filesystem. Format the card if needed.");
        } else {
            ESP_LOGE(TAG, "Failed to initialize the card (%s). Check pull-up resistors.", esp_err_to_name(ret));
        }
        return ret;
    }

    ESP_LOGI(TAG, "Filesystem mounted");
    sdmmc_card_print_info(stdout, card);
    return ESP_OK;
}

// 覆写文件
esp_err_t sdcard_write_file(const char *path, char *data) {
    // ESP_LOGI(TAG, "Opening file %s for writing", path);
    FILE *f = fopen(path, "w");
    if (!f) {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return ESP_FAIL;
    }
    fprintf(f, "%s", data);
    fclose(f);
    // ESP_LOGI(TAG, "File written successfully");
    return ESP_OK;
}

// 在文件后面追加内容
esp_err_t sdcard_append_file(const char *path, char *data) {
    // ESP_LOGI(TAG, "Opening file %s for appending", path);
    FILE *f = fopen(path, "a");
    if (!f) {
        ESP_LOGE(TAG, "Failed to open file for appending");
        return ESP_FAIL;
    }
    fprintf(f, "%s", data);
    fclose(f);
    // ESP_LOGI(TAG, "Data appended successfully");
    return ESP_OK;
}

// 读文件
esp_err_t sdcard_read_file(const char *path) {
    // ESP_LOGI(TAG, "Reading file %s", path);
    FILE *f = fopen(path, "r");
    if (!f) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return ESP_FAIL;
    }
    char line[MAX_CHAR_SIZE];
    fgets(line, sizeof(line), f);
    fclose(f);

    // 去除换行符
    char *pos = strchr(line, '\n');
    if (pos) {
        *pos = '\0';
    }
    ESP_LOGI(TAG, "Read from file: '%s'", line);
    return ESP_OK;
}

// 检查文件是否存在
bool file_exists(const char *path) {
    struct stat st;
    return stat(path, &st) == 0;
}

// 在追加之前检查文件
esp_err_t ensure_file_exists(const char *path) {
    if (!file_exists(path)) {
        // 创建文件
        FILE *f = fopen(path, "w");
        if (f == NULL) {
            printf("Failed to create file: %s\n", path);
            return ESP_FAIL;
        }
        fclose(f);
    }
    return ESP_OK;
}

// 卸载 SD 卡
void sdcard_unmount(void) {
    esp_vfs_fat_sdcard_unmount(MOUNT_POINT, card);
    ESP_LOGI(TAG, "Card unmounted");

    // 修正 spi_bus_free 的使用
    sdmmc_host_t host = SDSPI_HOST_DEFAULT();
    spi_bus_free(host.slot);
}

